module Pattern_Tx(
	input clk_in,		//主时钟
	input rst_n,		//复位信号，低有效
	input bps_clk,		//波特率时钟
	input[7:0] data,	//{[3:0],[3:0],[3:0],[7:0]}=={[数据位宽],[停止位宽],[校验方式],[待发送数据]}
	input[31:0] cot,	//发送参数配置{[3:0],[3:0],[3:0]}=={[数据位宽],[停止位宽],[校验方式]}
		
	output reg bps_en,	//传输开始信号，高有效
	output reg fr_flag,	//一次发送完成标志，高有效
	output reg rs232_tx	//UART输出数据
);
 
wire[3:0] DWidth,SWidth,Verify;
assign Verify = cot[3:0];	//校验方式 0无|1偶|2奇|3高电平|4低电平
assign SWidth = cot[7:4];	//停止位宽 2|3|4对应1|1.5|2
assign DWidth = cot[11:8];	//数据位宽 5|7|8对应5|7|8
wire[7:0] txdata;
assign txdata = data;	//待发送数据

reg initial_en_flag;
reg rx_bps_aa,rx_bps_bb,rx_bps_cc;
reg[7:0] state_c;
always@(posedge clk_in or negedge rst_n)
begin
	if(!rst_n)
	begin
		initial_en_flag <= 1'b0;
		bps_en <= 1'b0;
	end
	else
	begin
		initial_en_flag <= 1'b1;
		bps_en <= 1'b1;
	end
end

//状态寄存器
reg[7:0] state_n;
always@(posedge bps_clk or negedge rst_n)
begin
	if(!rst_n)
	begin
		state_c <= 8'h01;
	end
	else
	begin
		state_c <= state_n;
	end
end

//次态的组合逻辑
always@(state_c or initial_en_flag or Verify)
begin
	case(state_c)
		8'h01:begin//默认状态
				if(initial_en_flag)
				begin
                	state_n <= 8'h02;
                end
				else
				begin
                  	state_n <= 8'h01;
                end
			end
		8'h02:begin//状态1 发送起始位
				if(initial_en_flag)
				begin
					state_n <= 8'h03;
				end
				else
				begin
					state_n <= 8'h01;
				end
			end
		8'h03:begin//状态2 发送起始位
				if(initial_en_flag) 
				begin
					state_n <= 8'h04;
				end
				else    
				begin
					state_n <= 8'h01;
				end
			end
		8'h04:begin//状态3 发送[0]
				if(initial_en_flag) 
				begin
					state_n <= 8'h05;
				end
				else    
				begin
					state_n <= 8'h01;
				end
			end
		8'h05:begin//状态4 发送[0]
				if(initial_en_flag) 
				begin
					state_n <= 8'h06;
				end
				else    
				begin
					state_n <= 8'h01;
				end
			end
		8'h06:begin//状态5 发送[1]
				if(initial_en_flag) 
				begin
					state_n <= 8'h07;
				end
				else    
				begin
					state_n <= 8'h01;
				end
			end
		8'h07:begin//状态6 发送[1]
				if(initial_en_flag) 
				begin
					state_n <= 8'h08;
				end
				else    
				begin
					state_n <= 8'h01;
				end
			end
		8'h08:begin//状态7 发送[2]
				if(initial_en_flag) 
				begin
					state_n <= 8'h09;
				end
				else    
				begin
					state_n <= 8'h01;
				end
			end
		8'h09:begin//状态8 发送[2]
				if(initial_en_flag) 
				begin
					state_n <= 8'h0A;
				end
				else    
				begin
					state_n <= 8'h01;
				end
			end
		8'h0A:begin//状态9 发送[3]
				if(initial_en_flag) 
				begin
					state_n <= 8'h0B;
				end
				else    
				begin
					state_n <= 8'h01;
				end
			end
		8'h0B:begin//状态10 发送[3]
				if(initial_en_flag) 
				begin
					state_n <= 8'h0C;
				end
				else    
				begin
					state_n <= 8'h01;
				end
			end
		8'h0C:begin//状态11 发送[4]
				if(initial_en_flag) 
				begin
					state_n <= 8'h0D;
				end
				else    
				begin
					state_n <= 8'h01;
				end
			end
		8'h0D:begin//状态12 发送[4]
				if(initial_en_flag) 
				begin
					if(DWidth == 4'h5)
					begin
						case(Verify)
						4'h0:begin state_n <= 8'h1C;end	//无校验
						4'h1:begin state_n <= 8'h16;end	//偶校验
						4'h2:begin state_n <= 8'h14;end	//奇校验
						4'h3:begin state_n <= 8'h18;end	//1校验
						4'h4:begin state_n <= 8'h1A;end	//0校验
						default:begin state_n <= 8'h0D;end
						endcase						
					end
					else
					begin
						state_n <= 8'h0E;
					end
				end
				else    
				begin
					state_n <= 8'h01;
				end
			end
		8'h0E:begin//状态13 发送[5]
				if(initial_en_flag) 
				begin
					state_n <= 8'h0F;
				end
				else    
				begin
					state_n <= 8'h01;
				end
			end
		8'h0F:begin//状态14 发送[5]
				if(initial_en_flag) 
				begin
					state_n <= 8'h10;
				end
				else    
				begin
					state_n <= 8'h01;
				end
			end
		8'h10:begin//状态15 发送[6]
				if(initial_en_flag) 
				begin
					state_n <= 8'h11;
				end
				else    
				begin
					state_n <= 8'h01;
				end
			end
		8'h11:begin//状态16 发送[6]
				if(initial_en_flag) 
				begin
					if(DWidth == 4'h7)
					begin
						case(Verify)
						4'h0:begin state_n <= 8'h1C;end	//无校验
						4'h1:begin state_n <= 8'h16;end	//偶校验
						4'h2:begin state_n <= 8'h14;end	//奇校验
						4'h3:begin state_n <= 8'h18;end	//1校验
						4'h4:begin state_n <= 8'h1A;end	//0校验
						default:begin state_n <= 8'h11;end
						endcase						
					end
					else
					begin
						state_n <= 8'h12;
					end
				end
				else    
				begin
					state_n <= 8'h01;
				end
			end
		8'h12:begin//状态17 发送[7]
				if(initial_en_flag) 
				begin
					state_n <= 8'h13;
				end
				else    
				begin
					state_n <= 8'h01;
				end
			end
		8'h13:begin//状态18 发送[7]
				if(initial_en_flag) 
				begin
					case(Verify)
					4'h0:begin state_n <= 8'h1C;end	//无校验
					4'h1:begin state_n <= 8'h16;end	//偶校验
					4'h2:begin state_n <= 8'h14;end	//奇校验
					4'h3:begin state_n <= 8'h18;end	//1校验
					4'h4:begin state_n <= 8'h1A;end	//0校验
					default:begin state_n <= 8'h13;end
					endcase	
				end
				else    
				begin
					state_n <= 8'h01;
				end
			end
		8'h14:begin//状态19 发送奇校验
				if(initial_en_flag) 
				begin
					state_n <= 8'h15;
				end
				else    
				begin
					state_n <= 8'h01;
				end
			end
		8'h15:begin//状态20 发送奇校验
				if(initial_en_flag) 
				begin
					state_n <= 8'h1C;
				end
				else    
				begin
					state_n <= 8'h01;
				end
			end
		8'h16:begin//状态21 发送偶校验
				if(initial_en_flag) 
				begin
					state_n <= 8'h17;
				end
				else    
				begin
					state_n <= 8'h01;
				end
			end
		8'h17:begin//状态22 发送偶校验
				if(initial_en_flag) 
				begin
					state_n <= 8'h1C;
				end
				else    
				begin
					state_n <= 8'h01;
				end
			end
		8'h18:begin//状态23 发送1校验
				if(initial_en_flag) 
				begin
					state_n <= 8'h19;
				end
				else    
				begin
					state_n <= 8'h01;
				end
			end
		8'h19:begin//状态24 发送1校验
				if(initial_en_flag) 
				begin
					state_n <= 8'h1C;
				end
				else    
				begin
					state_n <= 8'h01;
				end
			end
		8'h1A:begin//状态25 发送0校验
				if(initial_en_flag) 
				begin
					state_n <= 8'h1B;
				end
				else    
				begin
					state_n <= 8'h01;
				end
			end
		8'h1B:begin//状态26 发送0校验
				if(initial_en_flag) 
				begin
					state_n <= 8'h1C;
				end
				else    
				begin
					state_n <= 8'h01;
				end
			end
		8'h1C:begin//状态27 发送停止位1
				if(initial_en_flag) 
				begin
//					state_n <= 8'h20;
					case(SWidth)
					4'h2:begin state_n <= 8'h20;end	//停止位1
					4'h3:begin state_n <= 8'h1F;end	//停止位1.5
					4'h4:begin state_n <= 8'h1E;end	//停止位2
					default:begin state_n <= 8'h1C;end
					endcase	
				end
				else    
				begin
					state_n <= 8'h01;
				end
			end
		8'h1D:begin//状态28 发送停止位1
				if(initial_en_flag) 
				begin
					state_n <= 8'h1E;
				end
				else    
				begin
					state_n <= 8'h01;
				end
			end
		8'h1E:begin//状态29 发送停止位1.5
				if(initial_en_flag) 
				begin
					state_n <= 8'h1F;
				end
				else    
				begin
					state_n <= 8'h01;
				end
			end
		8'h1F:begin//状态30 发送停止位2
				if(initial_en_flag) 
				begin
					state_n <= 8'h20;
				end
				else    
				begin
					state_n <= 8'h01;
				end
			end
		8'h20:begin//状态31 发送停止位2
				if(initial_en_flag) 
				begin
					state_n <= state_n;
				end
				else    
				begin
					state_n <= state_n;
				end
			end
			
		default:begin
        			state_n <= state_n;
			end
	endcase
end

//输出逻辑
always@(*)
begin
	case(state_c)
		8'h01:begin	//空闲位1
				rs232_tx <= 1'b1;
				fr_flag  <= 1'b0;
			end
		8'h02:begin	//起始位0
				rs232_tx <= 1'b0;
			end
		8'h03:begin	//起始位0
				rs232_tx <= 1'b0;
			end
		8'h04:begin	//发送[0]
				rs232_tx <= txdata[0];
			end
		8'h05:begin	//发送[0]
				rs232_tx <= txdata[0];
			end
		8'h06:begin	//发送[1]
				rs232_tx <= txdata[1];
			end
		8'h07:begin	//发送[1]
				rs232_tx <= txdata[1];
			end
		8'h08:begin	//发送[2]
				rs232_tx <= txdata[2];
			end
		8'h09:begin	//发送[2]
				rs232_tx <= txdata[2];
			end
		8'h0A:begin	//发送[3]
				rs232_tx <= txdata[3];
			end
		8'h0B:begin	//发送[3]
				rs232_tx <= txdata[3];
			end
		8'h0C:begin	//发送[4]
				rs232_tx <= txdata[4];
			end
		8'h0D:begin	//发送[4]
				rs232_tx <= txdata[4];
			end
		8'h0E:begin	//发送[5]
				rs232_tx <= txdata[5];
			end
		8'h0F:begin	//发送[5]
				rs232_tx <= txdata[5];
			end
		8'h10:begin	//发送[6]
				rs232_tx <= txdata[6];
			end
		8'h11:begin	//发送[6]
				rs232_tx <= txdata[6];
			end
		8'h12:begin	//发送[7]
				rs232_tx <= txdata[7];
			end
		8'h13:begin	//发送[7]
				rs232_tx <= txdata[7];
			end
		8'h14:begin	//发送奇校验
				rs232_tx <= ~^txdata;
			end
		8'h15:begin	//发送奇校验
				rs232_tx <= ~^txdata;
			end
		8'h16:begin	//发送偶校验
				rs232_tx <= ^txdata;
			end
		8'h17:begin	//发送偶校验
				rs232_tx <= ^txdata;
			end
		8'h18:begin	//发送1校验
				rs232_tx <= 1'b1;
			end
		8'h19:begin	//发送1校验
				rs232_tx <= 1'b1;
			end
		8'h1A:begin	//发送0校验
				rs232_tx <= 1'b0;
			end
		8'h1B:begin	//发送0校验
				rs232_tx <= 1'b0;
			end
		8'h1C:begin	//发送停止位1
				rs232_tx <= 1'b1;
			end
		8'h1D:begin	//发送停止位1
				rs232_tx <= 1'b1;
			end
		8'h1E:begin	//发送停止位1.5
				rs232_tx <= 1'b1;
			end
		8'h1F:begin	//发送停止位2
				rs232_tx <= 1'b1;
			end
		8'h20:begin	//发送停止位2
				rs232_tx <= 1'b1;
				fr_flag  <= 1'b1;
			end
			
		default:begin  
				rs232_tx <= rs232_tx;
			end
	endcase
end
 
endmodule
